package com.hourse.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.internal.LinkedTreeMap;
import com.hourse.app.entity.TickerEntity;
import com.hourse.app.service.PlatformOyxService;
import com.hourse.app.utils.DateUtil;
import com.hourse.app.vo.rms.TradesRetVo;
import com.hourse.app.vo.web.BalanceRetVo;
import com.hourse.app.vo.web.OrdersRetVo;
import com.hourse.app.vo.web.PublicDealRetVo;
import com.hourse.okx.config.APIConfiguration;
import com.hourse.okx.service.account.AccountAPIService;
import com.hourse.okx.service.account.impl.AccountAPIServiceImpl;
import com.hourse.okx.service.marketData.MarketDataAPIService;
import com.hourse.okx.service.marketData.impl.MarketDataAPIServiceImpl;
import com.hourse.okx.service.trade.TradeAPIService;
import com.hourse.okx.service.trade.impl.TradeAPIServiceImpl;
import com.hourse.platform.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @作者：lichenguang
 * @描述：【欧易平台】
 * @创建：2022/1/24 10:53
 */
@Slf4j
@Service
public class PlatformOyxServiceImpl implements PlatformOyxService {

  /**
   * @描述 ：【产品深度】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 15:53
   */
  @Override
  public Object getOrderBook(String currency, APIConfiguration config) throws AppException {
    try {
      MarketDataAPIServiceImpl marketDataAPIService = new MarketDataAPIServiceImpl(config);
      JSONObject result = marketDataAPIService.getOrderBook(currency, "20");
      log.info("=====> 查询欧易产品深度结果: {}", JSON.toJSONString(result));

      HashMap<String, List<TradesRetVo>> retMap = new HashMap<>();
      retMap.put("sell", new ArrayList<>());
      retMap.put("buy", new ArrayList<>());
      for (Object datum : result.getJSONArray("data")) {
        LinkedTreeMap item = (LinkedTreeMap) datum;
        ArrayList<ArrayList> asksList = (ArrayList<ArrayList>) item.get("asks");
        ArrayList<ArrayList> bidsList = (ArrayList<ArrayList>) item.get("bids");

        for (ArrayList asksInfos : asksList) {
          TradesRetVo vo = new TradesRetVo((String) item.get("ts"), (String) asksInfos.get(0), (String) asksInfos.get(1), "sell");
          retMap.get("sell").add(vo);
        }

        for (ArrayList bidsInfos : bidsList) {
          TradesRetVo vo = new TradesRetVo((String) item.get("ts"), (String) bidsInfos.get(0), (String) bidsInfos.get(1), "buy");
          retMap.get("buy").add(vo);
        }

      }

      return retMap;
    } catch (AppException e) {
      e.printStackTrace();
      throw new AppException("欧易查询产品深度异常，请检查对应账号配置");
    }
  }

  /**
   * @描述 ：【产品历史成交数据】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 16:12
   */
  @Override
  public Object getTrans(String currency, APIConfiguration config) throws AppException {

    try {
      MarketDataAPIServiceImpl marketDataAPIService = new MarketDataAPIServiceImpl(config);
      JSONObject result = marketDataAPIService.getTrades(currency, "20");
      log.info("=====> 查询欧易产品历史成交结果: {}", JSON.toJSONString(result));

      List<PublicDealRetVo> list = new ArrayList<>();
      for (Object datum : result.getJSONArray("data")) {
        LinkedTreeMap item = (LinkedTreeMap) datum;

        String ts = DateUtil.TimeStamp2Date((String) item.get("ts"), DateUtil.ptn_18);
        String px = (String) item.get("px");
        String sz = (String) item.get("sz");
        String side = (String) item.get("side");
        PublicDealRetVo tradesRetVo = new PublicDealRetVo(ts, px, sz, side);

        list.add(tradesRetVo);
      }
      return list;
    } catch (Exception e) {
      e.printStackTrace();
      throw new AppException("查询欧易产品历史成交异常，请检查对应账号配置");
    }
  }

  /**
   * @描述 ：【获取产品k线图数据】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 16:36
   */
  @Override
  public Object getK(String currency, String type, APIConfiguration config) throws AppException {

    try {
      MarketDataAPIServiceImpl marketDataAPIService = new MarketDataAPIServiceImpl(config);
      JSONObject result = marketDataAPIService.getIndexCandlesticks(currency, "", "", type, "300");
      log.info("=====> 查询欧易产品k线图数据结果: {}", JSON.toJSONString(result));

      String pattern = DateUtil.ptn_10;
      switch (type) {
        case "1m":
          pattern = "MM-dd HH:mm";
          break;
        case "1H":
          pattern = "MM-dd HH";
          break;
      }

      for (Object datum : result.getJSONArray("data")) {
        ArrayList item = (ArrayList) datum;
        String time = (String) item.get(0);
        String transitionTime = DateUtil.TimeStamp2Date(time, pattern);
        item.remove(0);
        item.add(0, transitionTime);

        long item1 = new BigDecimal(String.valueOf(item.get(1))).longValue();
        item.remove(1);
        item.add(1, item1);

        long item2 = new BigDecimal(String.valueOf(item.get(2))).longValue();
        item.remove(2);
        item.add(2, item2);

        long item3 = new BigDecimal(String.valueOf(item.get(3))).longValue();
        item.remove(3);
        item.add(3, item3);

        long item4 = new BigDecimal(String.valueOf(item.get(4))).longValue();
        item.remove(4);
        item.add(4, item4);
      }

      return result.getJSONArray("data");
    } catch (Exception e) {
      e.printStackTrace();
      throw new AppException("查询欧易产品历史成交异常，请检查对应账号配置");
    }
  }

  /**
   * @描述 ：【获取单个货币行情】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 16:39
   */
  @Override
  public Object getTicker(String market, APIConfiguration config) {
    TickerEntity tickerEntity = new TickerEntity();

    try {
      MarketDataAPIServiceImpl marketDataAPIService = new MarketDataAPIServiceImpl(config);
      JSONObject ticker = marketDataAPIService.getTicker(market);

      JSONArray data = ticker.getJSONArray("data");
      for (Object datum : data) {
        LinkedTreeMap item = ((LinkedTreeMap) datum);
        tickerEntity.setMarket(market);
        tickerEntity.setHigh((String) item.get("high24h"));
        tickerEntity.setLow((String) item.get("low24h"));
        tickerEntity.setLast((String) item.get("last"));
        tickerEntity.setOpen((String) item.get("open24h"));
      }

    } catch (AppException e) {
      e.printStackTrace();
    }

    return tickerEntity;
  }

  /**
   * @描述 ：【查看账户余额】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 13:19
   */
  @Override
  public Object balance(String currency, APIConfiguration config) throws AppException {

    AccountAPIService accountAPIService = new AccountAPIServiceImpl(config);

    List<BalanceRetVo> list = new ArrayList<>();
    try {
      String[] split = currency.split("-");
      JSONObject result = accountAPIService.getBalance(split[0]);
      log.info("=====> 查询欧易余额结果: {}", JSON.toJSONString(result));

      JSONArray data = result.getJSONArray("data");
      for (Object datum : data) {
        ArrayList details = (ArrayList) ((LinkedTreeMap) datum).get("details");
        for (Object detail : details) {
          LinkedTreeMap item = (LinkedTreeMap) detail;
          BalanceRetVo balanceRetVo = new BalanceRetVo();
          balanceRetVo.setCnName((String) item.get("ccy"));
          balanceRetVo.setAvailable((String) item.get("cashBal"));
          balanceRetVo.setFreez((String) item.get("ordFrozen"));
          list.add(balanceRetVo);
        }
      }
    } catch (AppException e) {
      e.printStackTrace();
      throw new AppException("欧易查询余额异常，请检查对应账号配置");
    }
    return list;
  }

  /**
   * @描述 ：【查看历史订单（3个月）】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 13:19
   */
  @Override
  public Object getOrders(String currency, APIConfiguration config) throws AppException {

    TradeAPIService tradeAPIService = new TradeAPIServiceImpl(config);

    JSONObject result = tradeAPIService.getOrderHistory3months("SPOT", "", currency,
      "", "", "", "", "");
    log.info("=====> 查询欧易查看历史订单(3个月)结果: {}", JSON.toJSONString(result));

    return this.orderDataJoint(result);

  }

  @Override
  public Object getOrdersPending(String currency, APIConfiguration config) throws AppException {

    TradeAPIService tradeAPIService = new TradeAPIServiceImpl(config);

    JSONObject result = tradeAPIService.getOrderList("SPOT", "", currency, "",
      "", "", "", "");
    log.info("=====> 查询欧易获取未成交订单列表结果: {}", JSON.toJSONString(result));

    return this.orderDataJoint(result);
  }

  @Override
  public Object order(String amount, String currency, String uKey, String uSecret, String price, String tradeType) throws AppException {
    return null;
  }



  /**
   * @描述 ：【订单信息处理】
   * @作者 ：lichenguang
   * @时间 ：2022/3/25 13:41
   */
  private List orderDataJoint(JSONObject result) {

    List<OrdersRetVo> list = new ArrayList<>();
    JSONArray data = result.getJSONArray("data");
    for (Object datum : data) {
      LinkedTreeMap item = ((LinkedTreeMap) datum);
      OrdersRetVo ordersRetVo = new OrdersRetVo();
      ordersRetVo.setCurrency((String) item.get("instId"));
      ordersRetVo.setTradeDate(DateUtil.TimeStamp2Date((String) item.get("cTime"), DateUtil.ptn_18));
      ordersRetVo.setType("buy".equals(item.get("side")) ? "卖" : "买");
      ordersRetVo.setPrice((String) item.get("px"));
      ordersRetVo.setTotalAmount((String) item.get("sz"));
      ordersRetVo.setTradeAmount((String) item.get("accFillSz"));
      ordersRetVo.setStatus("state".equals(item.get("canceled")) ? "撤单成功" : "完全成交");
      ordersRetVo.setFees((String) item.get("fee") + item.get("feeCcy"));

      list.add(ordersRetVo);
    }
    return list;

  }

}
